import React, {useCallback, useState, useRef, useMemo, useEffect} from 'react';
import {View, StyleSheet, Dimensions} from 'react-native';
const windowWidth = Dimensions.get('window').width;
// const windowHeight = Dimensions.get('window').height;
const Swiper = ({
  isAuto = false,
  width = windowWidth,
  height = windowWidth,
  speed = 4000, // 自动轮播时间间隔
  anmiteSpeed = 100, // 归位时间
  children = [],
  onChange = () => {},
  renderPagination = null,
  showRnderPagination = true,
  onScroll = () => {},
}) => {
  const timer = useRef(null); // 定时器
  const autoTimer = useRef(null); // 定时器
  const [x_, setX_] = useState(-windowWidth);
  const [swipeitemWidth, setSwipeitemWidth] = useState(windowWidth);
  const [touchStart, setTouchStart] = useState(0); // 按下按钮位置
  const [animateX, setAnimateX] = useState(0); // 按下按钮位置
  const currentX = useRef(x_); // 记录位移
  const translateX = useMemo(() => {
    currentX.current = x_ + animateX;
    return x_ + animateX;
  }, [x_, animateX]);
  const list = useMemo(() => {
    if (!children.length) {
      // 只有一个子元素
      return [children];
    }
    const len = children.length;
    if (len === 0) {
      // 没有原生不显示
      return [];
    } else {
      return [children[len - 1], ...children, children[0]];
    }
  }, [children]);
  const listLen = list.length;
  const actived = useMemo(() => {
    let a = -translateX / swipeitemWidth - 1;
    const b = a % 1;
    if (b >= 0.5) {
      a = parseInt(a + 1);
    } else {
      a = parseInt(a);
    }
    // console.log(a, 'a');
    if (a < 0) {
      return listLen - 3;
    } else if (a > listLen - 3) {
      return 0;
    } else {
      if (a === -0) {
        return 0;
      }
      return a;
    }
  }, [translateX, swipeitemWidth, listLen]);
  const scrollX = useMemo(() => {
    let a = -translateX - swipeitemWidth;
    if (a < 0) {
      return (listLen - 3) * swipeitemWidth + a;
    }
    if (a > (listLen - 3) * swipeitemWidth) {
      return a - (listLen - 3) * swipeitemWidth;
    }
    return a;
  }, [translateX, swipeitemWidth, listLen]);
  // console.log(scrollX, 'actived');

  const onTouchStart = useCallback(e => {
    // 按下清除定时器
    // 清除自动轮播定时器
    clearInterval(autoTimer.current);
    autoTimer.current = null;
    // 清除运动定时器
    clearInterval(timer.current);
    timer.current = null;
    const x = e.nativeEvent.pageX;
    setTouchStart(x);
    // console.log(x);
  }, []);
  const onTouchEnd = useCallback(
    e => {
      console.log('onTouchEnd');
      clearInterval(timer.current);
      timer.current = null;
      const x = e.nativeEvent.pageX - touchStart;
      const touchEndX = x_ + x;
      setX_(touchEndX);
      setAnimateX(0); // 抬起后恢复拖拽偏移量为0
      // 这里面判断要去哪里
      // const x = e.nativeEvent.pageX;
      // 因为移动的方向是反的，所以数据要取正数
      let num = parseInt(-touchEndX / swipeitemWidth);
      // console.log('num-> ', num);
      let trax = 0;
      let a = 0;
      // 算出剩下要运动的距离
      if (x > 0) {
        // 往前滑 num - 1 运动
        // num -= 1;
        trax = num * swipeitemWidth + touchEndX;
        // 速度是负的
        a = (trax * 16) / anmiteSpeed;
        // touchEndX 是负的所以是加
        // timer = setInterval(() => {
        // }, 16);
        // trax = num * swipeitemWidth + touchEndX;
        // const a = (trax * 16) / speed;
        // console.log(trax, '这个是运动的距离', requestAnimationFrame);
        // console.log(a, '这个是运动的速度');
        // console.log('往前滑', num, trax, touchEndX);
        let trx = touchEndX; // 开始距离
        timer.current = setInterval(() => {
          trx -= a; // 要减到对应的值
          if (-trx <= num * swipeitemWidth) {
            setX_(-num * swipeitemWidth);
            clearInterval(timer.current);
            timer.current = null;
            // 运动结束， 可预留回调函数执行
            // console.log('运动结束，', num);
            if (num === 0) {
              setX_(-(listLen - 2) * swipeitemWidth);
            }
            if (isAuto) {
              fn();
            }
          } else {
            setX_(trx);
          }
        }, 16);
      }
      if (x < 0) {
        // 往后滑 num + 1 运动
        num += 1;
        // touchEndX 是负的所以是加
        trax = num * swipeitemWidth + touchEndX;
        a = (trax * 16) / anmiteSpeed;
        // console.log(trax, '这个是运动的距离');
        // console.log(a, '这个是运动的速度');
        let trx = touchEndX; // 开始距离
        timer.current = setInterval(() => {
          trx -= a;
          if (-trx >= num * swipeitemWidth || trx > 1000) {
            setX_(-num * swipeitemWidth);
            clearInterval(timer.current);
            timer.current = null;
            // 运动结束， 可预留回调函数执行
            // console.log('运动结束，', num, list.length - 2);
            if (num === listLen - 1) {
              // console.log('最后一张了', -swipeitemWidth);
              setX_(-swipeitemWidth);
            }
            if (isAuto) {
              fn();
            }
          } else {
            setX_(trx);
          }
        }, 16);
        // console.log('往后滑', num, touchEndX, trax);
      }
      if (x === 0 && isAuto) {
        fn();
        console.log('点击了一下');
      }
      // console.log(x, 'touchStart');
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [
      touchStart,
      swipeitemWidth,
      x_,
      timer,
      anmiteSpeed,
      listLen,
      speed,
      translateX,
    ],
  );
  const onTouchMove = useCallback(
    e => {
      const x = e.nativeEvent.pageX - touchStart;
      // console.log(x, 'onTouchMove');
      setAnimateX(x);
    },
    [touchStart],
  );
  const fn = useCallback(() => {
    autoTimer.current = setInterval(() => {
      const x = currentX.current - 0;
      const count = roundingFn(x / swipeitemWidth);
      // console.log(count, 'count', x);
      const s = (swipeitemWidth * 16) / anmiteSpeed; // 速度
      // 速度是负的
      let distance = x;
      clearInterval(timer);
      timer.current = null;
      timer.current = setInterval(() => {
        distance -= s;
        // console.log(-distance >= swipeitemWidth - translateX, '-eX');
        if (-distance >= swipeitemWidth - x) {
          // 运动结束
          clearInterval(timer.current);
          timer.current = null;
          setX_((count - 1) * swipeitemWidth);
          if (-count >= listLen - 2) {
            setX_(-swipeitemWidth);
          }
        } else {
          setX_(distance);
        }
      }, 16);
    }, speed);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [speed, listLen, swipeitemWidth]);
  useEffect(() => {
    isAuto && fn();
    return () => {
      // 清除自动轮播定时器
      clearInterval(autoTimer.current);
      autoTimer.current = null;
      // 清除运动定时器
      clearInterval(timer.current);
      timer.current = null;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  useEffect(() => {
    onChange(actived);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [actived]);
  useEffect(() => {
    onScroll(scrollX);
    // console.log(-translateX - swipeitemWidth);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [scrollX]);
  const onLayout = e => {
    const w = e.nativeEvent.layout.width;
    setSwipeitemWidth(w);
    setX_(-w);
    // const height = e.nativeEvent.layout.height;
  };
  const swiperWarpStyle = {
    width,
    height,
  };
  const swiperItemStyle = {
    width: swipeitemWidth,
    height,
  };
  if (listLen === 0) {
    return null;
  }
  if (listLen === 1) {
    return children;
  }
  // console.log(listLen);
  return (
    <View onLayout={onLayout} style={[styles.swiperWarp, swiperWarpStyle]}>
      <View
        onTouchStart={onTouchStart}
        onTouchEnd={onTouchEnd}
        onTouchCancel={onTouchEnd}
        onTouchMove={onTouchMove}
        style={[
          styles.swiperWarp,
          {
            height: height,
            transform: [{translateX: translateX}],
          },
        ]}>
        {list.map((item, i) => {
          return (
            <View key={i} style={swiperItemStyle}>
              {item}
            </View>
          );
        })}
      </View>
      {}
      {showRnderPagination ? (
        <RenderPagination
          renderPagination={renderPagination}
          list={children}
          active={actived}
        />
      ) : null}
    </View>
  );
};

export default Swiper;

const RenderPagination = ({list, active, renderPagination}) => {
  if (renderPagination) {
    return renderPagination;
  }
  return (
    <View style={styles.pagination}>
      {list.map((item, index) => {
        return active === index ? (
          <View style={styles.paginationItemActive} key={index} />
        ) : (
          <View style={styles.paginationItem} key={index} />
        );
      })}
    </View>
  );
};

const roundingFn = num => {
  if (typeof num !== 'number') {
    return 0;
  }
  const n = parseInt(num * 10) % 10;
  return n < 5 ? parseInt(num) : parseInt(num) + 1;
};

const styles = StyleSheet.create({
  swiperWarp: {
    justifyContent: 'flex-start',
    flexDirection: 'row',
    flexWrap: 'nowrap',
    overflow: 'hidden',
    backgroundColor: '#f40',
    position: 'relative',
  },
  pagination: {
    position: 'absolute',
    height: 5,
    left: 0,
    right: 0,
    bottom: 10,
    marginLeft: '30%',
    marginRight: '30%',
    display: 'flex',
    justifyContent: 'center',
    flexDirection: 'row',
    alignItems: 'center',
  },
  paginationItem: {
    borderRadius: 50,
    backgroundColor: 'rgba(255,255,255,0.9)',
    width: 5,
    height: 5,
    marginLeft: 3,
    marginRight: 3,
  },
  paginationItemActive: {
    borderRadius: 50,
    backgroundColor: 'rgba(255,255,255,1)',
    width: 15,
    height: 5,
    marginLeft: 3,
    marginRight: 3,
  },
});
